import { Component, InfiniteGallery, WheelScroller, DragDetecter } from 'kokomi.js';
import type Experience from '../Experience';
import sliderVertexShader from '@/experience/shaders/slider/vert.glsl'
import sliderFragmentShader from '@/experience/shaders/slider/frag.glsl'

export default class Slider extends Component{

    declare base: Experience;

    public ig: InfiniteGallery;
    public ws: WheelScroller;
    public params: Record<string, any>;
    public dd: DragDetecter;

    constructor(base: Experience){
        super(base);

        const params = {
            uDistortX: {
                value: 1,
            },
            uDistortZ: {
                value: 1,
            },
        };
        this.params = params;

        this.ig = new InfiniteGallery(this.base, {
            elList: [...document.querySelectorAll('.gallery-item')] as InfiniteGallery['elList'],
            direction: 'horizontal',
            gap: 128,

            vertexShader: sliderVertexShader,
            fragmentShader: sliderFragmentShader,

            uniforms: {
                uVelocity: {
                    value: 0,
                },
                ...params,
            },
        });

        this.dd = new DragDetecter(this.base);
        this.dd.detectDrag();
        this.dd.on('drag', (delta: any) => {
            this.ws.scroll.target -= delta[this.ig.dimensionType] * 2;
        });

        const debug = this.base.debug;
        if(debug.active){
            const debugFolder = debug.ui?.addFolder('gallery');
            debugFolder?.add(params.uDistortX, 'value')
                .min(0)
                .max(2)
                .step(0.01)
                .name('distortX');
            debugFolder?.add(params.uDistortZ, 'value')
                .min(0)
                .max(2)
                .step(0.01)
                .name('distortZ');
        }

        this.ws = new WheelScroller();
        this.ws.listenForScroll();

    }

    async addExisting(){

        this.ig.addExisting();
        
        await this.ig.checkImagesLoaded();

    }

    update(){
        this.ws.syncScroll();
        const { current, delta } = this.ws.scroll;
        this.ig.sync(current);

        this.ig.iterate((maku) => {
            maku.mesh.material.uniforms.uVelocity.value = delta;

            maku.mesh.material.uniforms.uDistortX.value = this.params.uDistortX.value;
            maku.mesh.material.uniforms.uDistortZ.value = this.params.uDistortZ.value;
        });
    }
}